package com.yc.junit;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.*;
import java.util.*;


public class MathBizTest {
    MathBiz biz;
    @Test(1)
    public void test1(){
        System.out.println("-------- test1 --------");
        int res = biz.add(1, 1);
        Assert.assertEquals(2, res);
    }
    @Test(3)
    public void test2(){
        System.out.println("-------- test2 --------");
        int res = biz.sub(1, 1);
        Assert.assertEquals(0, res);
    }
    @Test(5)
    public void test3(){
        System.out.println("-------- test3 --------");
        int res = biz.mul(1, 1);
        Assert.assertEquals(1, res);
    }
    @Test(2)
    public void test4(){
        System.out.println("-------- test4 --------");
        int res = biz.div(1, 1);
        Assert.assertEquals(1, res);
    }
    @Test(4)
    public void test5(){
        System.out.println("-------- test5 --------");
        int res = biz.pow(2);
        Assert.assertEquals(4, res);
    }
    // 每个测试方法执行前执行的方法
    @Before
    public void before(){
        System.out.println("======== before =======");
        biz = new MathBiz();
    }
    // 每个测试方法执行后执行的方法
    @After
    public void after(){
        System.out.println("======== after =======");
        biz = null;
    }

    public static void main(String[] args) {
        // 完成单元测试
        Object tester = new MathBizTest();

        List<String> zq = new ArrayList<>();//存正确方法
        List<String>  cw = new ArrayList<>();//存错误方法
        List<String> yc = new ArrayList<>();//存异常方法


        // 提取方法 => 分类
        List<Method> tests = new ArrayList<>();
        List<Method> befores = new ArrayList<>();
        List<Method> afters = new ArrayList<>();

        Class<?> aClass = tester.getClass();
        Method[] methods = aClass.getDeclaredMethods();
        for (Method method : methods) {
            if(method.getAnnotation(Test.class)!=null){
                tests.add(method);
            } else if(method.getAnnotation(Before.class)!=null){
                befores.add(method);
            } if(method.getAnnotation(After.class)!=null){
                afters.add(method);
            }
        }

        // TODO 请对 tests 里面的方法进行排序

        Collections.sort(tests, new Comparator<Method>() {
            @Override
            public int compare(Method method1, Method method2) {
                int orderValue1 =   method1.getAnnotation(Test.class).value();
                int orderValue2 =  method2.getAnnotation(Test.class).value();
                return Integer.compare(orderValue1, orderValue2);
            }
        });



        // 打印排序后的测试方法
        for (Method test : tests) {
            System.out.println(test.getName());
        }

        // 循环完成
        for (Method test : tests) {
            // 执行 before 方法
            for (Method before : befores) {
                try{
                    before.invoke(tester);
                } catch (Exception e){
                    throw new RuntimeException("before 方法执行错误", e);
                }
            }
            // 执行测试方法
            try {
                test.invoke(tester);
                // TODO 统计为正确方法
                zq.add(test.getName());
            } catch (IllegalAccessException e) {
                throw new RuntimeException("测试方法访问错误");
            } catch (InvocationTargetException e) {
                Throwable cause = e.getCause();
                if( cause instanceof AssertException){
                    // TODO 统计为错误方法
                    cw.add(test.getName());
                } else {
                    // TODO 统计为异常方法
                    yc.add(test.getName());
                }
            }
            // 执行 after 方法
            for (Method after : afters) {
                try{
                    after.invoke(tester);
                } catch (Exception e){
                    throw new RuntimeException("after 方法执行错误", e);
                }
            }
        }
        // 统计结果 => 显示结果

        System.out.println("***********正确的***************");
        for (String s : zq) {
            System.out.println(s);
        }
        System.out.println("*************错误的*************");
        for (String c : cw) {
            System.out.println(c);
        }
        System.out.println("************异常的**************");
        for (String y : yc) {
            System.out.println(y);
        }

    }
}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Test{
    int value();
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Before{
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface After{
}

// 断言异常
class AssertException extends RuntimeException{
    public AssertException(String message) {
        super(message);
    }
}

// 断言
class Assert{
    public static void assertEquals(Object o1, Object o2) {
        if(o1 != null && o2 != null && o1==o2){

            return;
        } else if( (o1==null || o2 == null ||o1!=o2 )
                ){
            throw new AssertException("结果不正确");
        }
    }
}

